﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio;

namespace mdv.wssSchemaExplorer
{
    /// <summary>
    /// This class implements the tool window exposed by this package and hosts a user control.
    ///
    /// In Visual Studio tool windows are composed of a frame (implemented by the shell) and a pane, 
    /// usually implemented by the package implementer.
    ///
    /// This class derives from the ToolWindowPane class provided from the MPF in order to use its 
    /// implementation of the IVsWindowPane interface.
    /// </summary>
    [Guid("7a273597-da26-4bef-8b3f-751133ebfc01")]
    public class MyToolWindow : ToolWindowPane,
                                IVsSelectionEvents //Notifies registered VSPackages of changes to the current selection, element value, or command UI context. 
    {
        // This is the user control hosted by the tool window; it is exposed to the base class 
        // using the Window property. Note that, even if this class implements IDispose, we are
        // not calling Dispose on this object. This is because ToolWindowPane calls Dispose on 
        // the object returned by the Window property.
        private MyControl control;
        private String previousFullPath = String.Empty;

        /// <summary>
        /// Standard constructor for the tool window.
        /// </summary>
        public MyToolWindow() :
            base(null)
        {
            // Set the window title reading it from the resources.
            this.Caption = Resources.ToolWindowTitle;
            // Set the image that will appear on the tab of the window frame
            // when docked with an other window
            // The resource ID correspond to the one defined in the resx file
            // while the Index is the offset in the bitmap strip. Each image in
            // the strip being 16x16.
            this.BitmapResourceID = 301;
            this.BitmapIndex = 1;
            control = new MyControl(this);
        }

        /// <summary>
        /// This property returns the handle to the user control that should
        /// be hosted in the Tool Window.
        /// </summary>
        override public IWin32Window Window
        {
            get
            {
                return (IWin32Window)control;
            }
        }
        private ITrackSelection trackSel;
        private ITrackSelection TrackSelection
        {
            get
            {
                if (trackSel == null)
                    trackSel = GetService(typeof(STrackSelection)) as ITrackSelection;
                return trackSel;
            }
        }
        private IVsMonitorSelection monitorSel;
        private IVsMonitorSelection MonitorSelection
        {
            get
            {
                if(monitorSel == null)
                    monitorSel = GetService(typeof(SVsShellMonitorSelection)) as IVsMonitorSelection;
                return monitorSel;
            }
        }
        private SelectionContainer selContainer;
        public void UpdateSelection()
        {
            ITrackSelection track = TrackSelection;
            if (track != null)
                track.OnSelectChange((ISelectionContainer)selContainer);
        }
        public void SelectList(ICollection list)
        {
            selContainer = new SelectionContainer(true, false);
            selContainer.SelectableObjects = list;
            selContainer.SelectedObjects = list;
            UpdateSelection();
        }
        private uint selectionCookie;
        protected override void Initialize()
        {
            MonitorSelection.AdviseSelectionEvents(this, out selectionCookie);
        }
        protected override void Dispose(bool disposing)
        {
            if (disposing && (this.selectionCookie != 0))
            {
                MonitorSelection.UnadviseSelectionEvents(this.selectionCookie);
                this.selectionCookie = 0;
            }
        }

        #region IVsSelectionEvents Members
        public int OnCmdUIContextChanged(uint dwCmdUICookie, int fActive)
        {
            return VSConstants.S_OK;
        }
        public int OnElementValueChanged(uint elementid, object varValueOld, object varValueNew)
        {
            return VSConstants.S_OK;
        }
        public int OnSelectionChanged(IVsHierarchy pHierOld, uint itemidOld, IVsMultiItemSelect pMISOld, ISelectionContainer pSCOld, IVsHierarchy pHierNew, uint itemidNew, IVsMultiItemSelect pMISNew, ISelectionContainer pSCNew)
        {
            if (pHierNew != null)
            {
                string fullPath;
                pHierNew.GetCanonicalName(itemidNew, out fullPath);
                if (fullPath != null && fullPath.ToString().EndsWith("schema.xml") && fullPath != previousFullPath)
                {
                    previousFullPath = fullPath;
                    control.LoadSchema(fullPath);
                }
            }
            return VSConstants.S_OK;
        }
        #endregion
    }
}